package study.domain.blog;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Size;

import lombok.Data;
import lombok.EqualsAndHashCode;

import org.hibernate.validator.constraints.NotEmpty;

import study.domain.attachment.Attachment;
import study.domain.user.User;

import com.barney.support.domain.HasCreatedAndUpdatedDate;
import com.barney.support.jpa.CreatedAndUpdatedDateListener;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

@Entity(name = "posts")
@Data
@EqualsAndHashCode(of = { "id" })
@EntityListeners(CreatedAndUpdatedDateListener.class)
public class Post implements Serializable, HasCreatedAndUpdatedDate {

	private static final long serialVersionUID = 2572698877781660268L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column
	private Long id;

	@OneToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "user_id", nullable = false, updatable = false)
	@org.hibernate.annotations.ForeignKey(name = "fk_posts_user_id")
	private User user;

	@NotEmpty
	@Size(min = 2, max = 100)
	@Column(nullable = false, length = 100)
	private String title;

	@ElementCollection(fetch = FetchType.LAZY)
	@CollectionTable(name = "post_contents_holders",
			joinColumns = @JoinColumn(name = "post_id", unique = true))
	@org.hibernate.annotations.ForeignKey(name = "fk_post_contents_holders_post_id")
	@Lob
	@Column(name = "contents", nullable = false)
	private Collection<String> contentsHolder;

	@Column(nullable = false)
	private int commentCount = 0;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(nullable = false, updatable = false)
	private Date createdDate;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(nullable = false)
	private Date updatedDate;

	@Column(nullable = false)
	private boolean deleted;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(nullable = true, updatable = false)
	private Date deletedDate;

	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "post_attachments", joinColumns = @JoinColumn(name = "post_id"),
			inverseJoinColumns = @JoinColumn(name = "attachment_id"))
	@org.hibernate.annotations.ForeignKey(name = "fk_post_attachments_post_id",
			inverseName = "fk_post_attachments_attachment_id")
	private List<Attachment> attachments;

	@OneToMany(mappedBy = "post", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	private Collection<Comment> comments;

	public Post() {
		//
	}

	public Post(Long id) {
		this.id = id;
	}

	public String getContents() {
		if (contentsHolder == null) {
			return "";
		}
		return Iterables.getFirst(contentsHolder, "");
	}

	public void setContents(String contents) {
		if (contentsHolder == null) {
			contentsHolder = Lists.newArrayList();
		}
		contentsHolder.clear();
		contentsHolder.add(contents);
	}
}
